#include "SubjectManager.h"


sSubjectId SubjectManager::newSubject(string subject) {
    uShort size = 2 + subject.size() + 1;
    sRow row = claimNewRow(size);
    row.header.bytes[0] = 0xA0;
    int2ToBytes(row.bytes, size - 2);
    strcpy_s(reinterpret_cast<char*>(row.bytes + 2), size - 2, subject.c_str());
    row.bytes[size - 1] = 0x0;
    sSubjectId res = row.header.valueId;
    BufferManager::setModified(res.blockId);
    BufferManager::unpinBlock(res.blockId);
    return res;
}

string SubjectManager::getSubject(sSubjectId sId) {
    sRow row = getRow(sId);
	if ((row.header.bytes[0] & M_1011_x4) != 0xA0)
        throw ERR_NO_SUBJECT_ROW;

    string res = string(reinterpret_cast<char*>(row.bytes + 2));
    BufferManager::unpinBlock(sId.blockId);

    return res;
}

sSubjectId SubjectManager::findSubject(string subject) {
    Block* block;
    blockId bId = 0;
    while (bId < DiscManager::getDiscSize()) {
        block = BufferManager::pinBlock(bId);
        if (block->isFree()) {
            bId++;
            break;
        }
        uShort rowCount = block->getRowCount();
        rowId rId = 0;
        while (rId < rowCount) {
            sRow row = block->getRow(rId);
			if ((row.header.bytes[0] & M_1011_x4) == 0xA0) {
                if (subject.length() == bytesToInt2(row.bytes) - 1)	//String haben gleiche Laenge
                {
                    //langsam, aber sicher-->Ersatz muss her
                    bool equal = true;
					for (uShort i = 0; equal && i < subject.length(); i++)
                        equal = (subject.c_str()[i] == reinterpret_cast<char*>(row.bytes + 2)[i]);
                    if (equal) {
                        BufferManager::unpinBlock(bId);
                        return sSubjectId{ bId, rId };
                    }
                    //Auskommentiert, da anscheinend manchmal(?) fehlerhaft
                    /*if (strcmp(subject.c_str(), reinterpret_cast<char*>(row.bytes + 2)) == 0)
                    {
                    BufferManager::unpinBlock(bId);
                    return sSubjectId{ bId, rId };
                    }*/
                }
            }
            rId++;
        }
        BufferManager::unpinBlock(bId);
        bId++;
    }
    throw ERR_SUBJECT_DOES_NOT_EXIST;
}

bool SubjectManager::freeSubject(sSubjectId sId) {
    BufferManager::unpinBlock(sId.blockId);
    return true;
}

sSubjectId SubjectManager::bytesToSubjectId(const byte* bytes) {
    return bytesToValueId(bytes);
}
